import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import {
  PRESET_ITEMS_TRANSLATION,
  DURATION_UNIT,
  DEFAULT_PRESET_ITEMS_DATA,
} from "./constant";
import {
  PresetValue,
  DurationUnitType,
  DurationUnitTypeUnitTypeTranslation,
  TimeMarkType,
  Timestamp,
} from "./type";

dayjs.extend(duration);

function getDurationISOStringUnit(durationISOString: string): any {
  const lastChart = durationISOString.charAt(durationISOString.length - 1);
  // T为时间分量之前的指示符， 月M和分M需要区别
  const isMinutesDuration =
    lastChart === "M" && durationISOString.indexOf("T") > 0;
  return lastChart === "M" && !isMinutesDuration
    ? "M"
    : lastChart.toLowerCase();
}

const getIsoDurationInfo = (durationISOString: string) => {
  const durationUnit = getDurationISOStringUnit(
    durationISOString
  ) as DurationUnitType;
  const value = dayjs.duration(durationISOString).as(durationUnit);
  return {
    value,
    unit: durationUnit,
    translation: `最近${value}${DurationUnitTypeUnitTypeTranslation[durationUnit]}`,
  };
};

const getTimeMarkValueType = (
  timeMark: string | undefined,
  presetItems: PresetValue[]
): TimeMarkType => {
  if (!timeMark) {
    return undefined;
  }
  if (presetItems.includes(timeMark as any)) {
    return "preset";
  }
  const isDuration = DURATION_UNIT.includes(getDurationISOStringUnit(timeMark));
  if (isDuration) {
    return "duration";
  }
  const isTimeRange = timeMark.indexOf("/") > -1;
  if (isTimeRange) {
    return "timeRange";
  }
  return undefined;
};

const getTimeRangeTextInner = (
  timeMark: string | undefined,
  presetItems: PresetValue[]
) => {
  const timeMarkType = getTimeMarkValueType(timeMark, presetItems);
  if (!timeMark || !timeMarkType) {
    return "请选择时间范围";
  }
  if (timeMarkType === "preset") {
    return PRESET_ITEMS_TRANSLATION[timeMark as PresetValue];
  }
  if (timeMarkType === "duration") {
    const { translation } = getIsoDurationInfo(timeMark);
    return translation;
  }
  if (timeMarkType === "timeRange") {
    const [start, end] = timeMark?.split("/");
    const startVal = start
      ? dayjs(Number(start)).format("YYYY-MM-DD HH:mm:ss")
      : "";
    const endVal = end ? dayjs(Number(end)).format("YYYY-MM-DD HH:mm:ss") : "";
    return `${startVal} - ${endVal}`;
  }
};

const getPresetTimeRange = (value: string) => {
  if (value === PresetValue.TODAY) {
    return {
      start: dayjs().startOf("d").valueOf(),
      end: dayjs().endOf("d").valueOf(),
    };
  }
  if (value === PresetValue.YESTERDAY) {
    return {
      start: dayjs().subtract(1, "d").startOf("d").valueOf(),
      end: dayjs().subtract(1, "d").endOf("d").valueOf(),
    };
  }
  if (value === PresetValue.THIS_WEEK) {
    return {
      start: dayjs().add(-1, "day").startOf("w").add(1, "day").valueOf(),
      end: dayjs().add(-1, "day").endOf("w").add(1, "day").valueOf(),
    };
  }
  if (value === PresetValue.LAST_WEEK) {
    return {
      start: dayjs()
        .add(-1, "day")
        .add(-1, "week")
        .startOf("week")
        .add(1, "day")
        .valueOf(),
      end: dayjs()
        .add(-1, "day")
        .add(-1, "week")
        .endOf("week")
        .add(1, "day")
        .valueOf(),
    };
  }
  if (value === PresetValue.THIS_MONTH) {
    return {
      start: dayjs().startOf("M").valueOf(),
      end: dayjs().endOf("M").valueOf(),
    };
  }
  if (value === PresetValue.LAST_MONTH) {
    return {
      start: dayjs().subtract(1, "M").startOf("M").valueOf(),
      end: dayjs().subtract(1, "M").endOf("M").valueOf(),
    };
  }
  return {
    start: new Date().getTime(),
    end: new Date().getTime(),
  };
};

const getDurationTimeRange = (durationISOString: string) => {
  const { value, unit } = getIsoDurationInfo(durationISOString);
  return {
    start: dayjs().subtract(value, unit).valueOf(),
    end: new Date().getTime(),
  };
};

const getISOString = (value: number | undefined, unit: string) => {
  if (value) {
    const mark = dayjs.duration(value, unit as DurationUnitType).toISOString();
    //start 时间为NaN或小于0或start>end, 返回undefined
    const { start, end } = getDurationTimeRange(mark);
    if (Number.isNaN(start) || start <= 0 || start > end) return;
    return mark;
  }
};

const transTimeValueStringToTimestamp = (
  timeMark: string,
  presetItems?: PresetValue[]
): Timestamp => {
  const presetItemsData = presetItems ?? DEFAULT_PRESET_ITEMS_DATA;
  const timeMarkType = getTimeMarkValueType(timeMark, presetItemsData);
  if (timeMarkType && timeMarkType === "preset") {
    return getPresetTimeRange(timeMark);
  }
  if (timeMarkType && timeMarkType === "timeRange") {
    const timeArr = timeMark.split("/");
    return {
      start: Number(timeArr[0]),
      end: Number(timeArr[1]),
    };
  }
  if (timeMarkType && timeMarkType === "duration") {
    return getDurationTimeRange(timeMark);
  }
  return {
    start: new Date().getTime(),
    end: new Date().getTime(),
  };
};

export {
  getTimeRangeTextInner,
  getDurationTimeRange,
  getPresetTimeRange,
  getIsoDurationInfo,
  getISOString,
  getTimeMarkValueType,
  transTimeValueStringToTimestamp,
};
